home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / gas / gassrc04.zoo / write.c < prev    next >
C/C++ Source or Header  |  1993-03-02  |  39KB  |  1,262 lines

  1. /* write.c - emit .o file - Copyright(C)1986 Free Software Foundation, Inc.
  2.    Copyright (C) 1986,1987 Free Software Foundation, Inc.
  3.  
  4. This file is part of GAS, the GNU Assembler.
  5.  
  6. GAS is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GAS is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GAS; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /* 
  21.  
  22.    Umm, with real good luck, this thing should be set up to do byteordering
  23.    correctly, but I may have managed to miss a place or two.  Treat a.out
  24.    very carefully until you're SURE that it works. . .
  25.  
  26.    In order to cross-assemble the target machine must have an a.out header
  27.    similar to the one in a.out.h on THIS machine.  Byteorder doesn't matter;
  28.    we take special care of it, but the numbers must be the same SIZE (# of
  29.    bytes) and in the same PLACE.  If this is not true, you will have some
  30.    trouble.
  31.  */
  32.  
  33. #include "as.h"
  34. #include "md.h"
  35. #include "subsegs.h"
  36. #include "obstack.h"
  37. #include "struc-symbol.h"
  38. #include "write.h"
  39. #include "symbols.h"
  40.  
  41. #ifdef SPARC
  42. #include "sparc.h"
  43. #endif
  44. #ifdef I860
  45. #include "i860.h"
  46. #endif
  47.  
  48. void    append();
  49.  
  50. #ifndef CROSSHPUX
  51. #ifdef hpux
  52. #define EXEC_MACHINE_TYPE HP9000S200_ID
  53. #endif
  54. #endif
  55.  
  56. #ifdef DOT_LABEL_PREFIX
  57. #define LOCAL_LABEL(name) (name[0] =='.' \
  58.                          && ( name [1] == 'L' || name [1] == '.' ))
  59. #else  /* not defined DOT_LABEL_PREFIX */
  60. #define LOCAL_LABEL(name) (name [0] == 'L' )
  61. #endif /* not defined DOT_LABEL_PREFIX */
  62.  
  63. /*
  64.  * In: length of relocation (or of address) in chars: 1, 2 or 4.
  65.  * Out: GNU LD relocation length code: 0, 1, or 2.
  66.  */
  67.  
  68. static unsigned char
  69.  
  70. nbytes_r_length [] = {
  71.   42, 0, 1, 42, 2
  72.   };
  73.  
  74.  
  75. static struct frag *    text_frag_root;
  76. static struct frag *    data_frag_root;
  77.  
  78. static struct frag *    text_last_frag;    /* Last frag in segment. */
  79. static struct frag *    data_last_frag;    /* Last frag in segment. */
  80.  
  81. static struct exec    the_exec;
  82.  
  83. static long int string_byte_count;
  84.  
  85. static char *        the_object_file;
  86.  
  87. #if !defined(SPARC) && !defined(I860)
  88. static
  89. #endif
  90. char *        next_object_file_charP;    /* Tracks object file bytes. */
  91.  
  92. static long int        size_of_the_object_file; /* # bytes in object file. */
  93.  
  94. /* static long int        length; JF unused */    /* String length, including trailing '\0'. */
  95.  
  96. static void    relax_segment();
  97. void        emit_segment();
  98. static relax_addressT    relax_align();
  99. static long int    fixup_segment();
  100. #if !defined(SPARC) && !defined(I860)
  101. static void        emit_relocations();
  102. #endif
  103. /*
  104.  *            fix_new()
  105.  *
  106.  * Create a fixS in obstack 'notes'.
  107.  */
  108. void
  109. #if defined(SPARC) || defined(I860)
  110. fix_new (frag, where, size, add_symbol, sub_symbol, offset, pcrel, r_type)
  111. #else
  112. fix_new (frag, where, size, add_symbol, sub_symbol, offset, pcrel)
  113. #endif
  114.      fragS *    frag;        /* Which frag? */
  115.      int    where;        /* Where in that frag? */
  116.      short int    size;        /* 1, 2  or 4 usually. */
  117.      symbolS *    add_symbol;    /* X_add_symbol. */
  118.      symbolS *    sub_symbol;    /* X_subtract_symbol. */
  119.      long int    offset;        /* X_add_number. */
  120.      int    pcrel;        /* TRUE if PC-relative relocation. */
  121. #if defined(SPARC) || defined(I860)
  122.     int        r_type;
  123. #endif
  124. {
  125.   register fixS *    fixP;
  126.  
  127.   fixP = (fixS *)obstack_alloc(¬es,sizeof(fixS));
  128.  
  129.   fixP -> fx_frag    = frag;
  130.   fixP -> fx_where    = where;
  131.   fixP -> fx_size    = size;
  132.   fixP -> fx_addsy    = add_symbol;
  133.   fixP -> fx_subsy    = sub_symbol;
  134.   fixP -> fx_offset    = offset;
  135.   fixP -> fx_pcrel    = pcrel;
  136.   fixP -> fx_next    = * seg_fix_rootP;
  137.  
  138.   /* JF these 'cuz of the NS32K stuff */
  139.   fixP -> fx_im_disp    = 0;
  140.   fixP -> fx_pcrel_adjust = 0;
  141.   fixP -> fx_bsr    = 0;
  142.   fixP ->fx_bit_fixP    = 0;
  143.  
  144. #if defined(SPARC) || defined(I860)
  145.   fixP->fx_r_type = r_type;
  146. #endif
  147.  
  148.   * seg_fix_rootP = fixP;
  149. }
  150.  
  151. void
  152. write_object_file()
  153. {
  154.   register struct frchain *    frchainP; /* Track along all frchains. */
  155.   register fragS *        fragP;    /* Track along all frags. */
  156.   register struct frchain *    next_frchainP;
  157.   register fragS * *        prev_fragPP;
  158.   register char *        name;
  159.   register symbolS *        symbolP;
  160.   register symbolS **        symbolPP;
  161.   /* register fixS *        fixP; JF unused */
  162.   unsigned
  163.       text_siz,
  164.     data_siz,
  165.     syms_siz,
  166.     tr_siz,
  167.     dr_siz;
  168.   void output_file_create();
  169.   void output_file_append();
  170.   void output_file_close();
  171. #ifdef DONTDEF
  172.   void gdb_emit();
  173.   void gdb_end();
  174. #endif
  175.   extern long omagic;        /* JF magic # to write out.  Is different for
  176.                    Suns and Vaxen and other boxes */
  177.  
  178. #ifdef    VMS
  179.   /*
  180.    *    Under VMS we try to be compatible with VAX-11 "C".  Thus, we
  181.    *    call a routine to check for the definition of the procedure
  182.    *    "_main", and if so -- fix it up so that it can be program
  183.    *    entry point.
  184.    */
  185.   VMS_Check_For_Main();
  186. #endif /* VMS */
  187.   /*
  188.    * After every sub-segment, we fake an ".align ...". This conforms to BSD4.2
  189.    * brane-damage. We then fake ".fill 0" because that is the kind of frag
  190.    * that requires least thought. ".align" frags like to have a following
  191.    * frag since that makes calculating their intended length trivial.
  192.    */
  193. #define SUB_SEGMENT_ALIGN (2)
  194.   for ( frchainP=frchain_root; frchainP; frchainP=frchainP->frch_next )
  195.     {
  196. #ifdef    VMS
  197.       /*
  198.        *    Under VAX/VMS, the linker (and PSECT specifications)
  199.        *    take care of correctly aligning the segments.
  200.        *    Doing the alignment here (on initialized data) can
  201.        *    mess up the calculation of global data PSECT sizes.
  202.        */
  203. #undef    SUB_SEGMENT_ALIGN
  204. #define    SUB_SEGMENT_ALIGN ((frchainP->frch_seg != SEG_DATA) ? 2 : 0)
  205. #endif    /* VMS */
  206.       subseg_new (frchainP -> frch_seg, frchainP -> frch_subseg);
  207.       frag_align (SUB_SEGMENT_ALIGN, 0);
  208.                 /* frag_align will have left a new frag. */
  209.                 /* Use this last frag for an empty ".fill". */
  210.       /*
  211.        * For this segment ...
  212.        * Create a last frag. Do not leave a "being filled in frag".
  213.        */
  214.       frag_wane (frag_now);
  215.       frag_now -> fr_fix    = 0;
  216.       know( frag_now -> fr_next == NULL );
  217.       /* know( frags . obstack_c_base == frags . obstack_c_next_free ); */
  218.       /* Above shows we haven't left a half-completed object on obstack. */
  219.     }
  220.  
  221.   /*
  222.    * From now on, we don't care about sub-segments.
  223.    * Build one frag chain for each segment. Linked thru fr_next.
  224.    * We know that there is at least 1 text frchain & at least 1 data frchain.
  225.    */
  226.   prev_fragPP = &text_frag_root;
  227.   for ( frchainP=frchain_root; frchainP; frchainP=next_frchainP )
  228.     {
  229.       know( frchainP -> frch_root );
  230.       * prev_fragPP = frchainP -> frch_root;
  231.       prev_fragPP = & frchainP -> frch_last -> fr_next;
  232.       if (   ((next_frchainP = frchainP->frch_next) == NULL)
  233.       || next_frchainP == data0_frchainP)
  234.     {
  235.       prev_fragPP = & data_frag_root;
  236.       if ( next_frchainP )
  237.         {
  238.           text_last_frag = frchainP -> frch_last;
  239.         }
  240.       else
  241.         {
  242.           data_last_frag = frchainP -> frch_last;
  243.         }
  244.     }
  245.     }                /* for(each struct frchain) */
  246.  
  247.   /*
  248.    * We have two segments. If user gave -R flag, then we must put the
  249.    * data frags into the text segment. Do this before relaxing so
  250.    * we know to take advantage of -R and make shorter addresses.
  251.    */
  252.   if ( flagseen [ 'R' ] )
  253.     {
  254.       fixS *tmp;
  255.  
  256.       text_last_frag -> fr_next = data_frag_root;
  257.       text_last_frag = data_last_frag;
  258.       data_last_frag = NULL;
  259.       data_frag_root = NULL;
  260.       if(text_fix_root) {
  261.     for(tmp=text_fix_root;tmp->fx_next;tmp=tmp->fx_next)
  262.       ;
  263.     tmp->fx_next=data_fix_root;
  264.       } else
  265.         text_fix_root=data_fix_root;
  266.       data_fix_root=NULL;
  267.     }
  268.  
  269.   relax_segment (text_frag_root, SEG_TEXT);
  270.   relax_segment (data_frag_root, SEG_DATA);
  271.   /*
  272.    * Now the addresses of frags are correct within the segment.
  273.    */
  274.  
  275.   know(   text_last_frag -> fr_type   == rs_fill && text_last_frag -> fr_offset == 0 );
  276.   text_siz=text_last_frag->fr_address;
  277. #ifdef SPARC
  278.   text_siz= (text_siz+7)&(~7);
  279.   te